#include "rtda/heap/slots.h"
#include <cmath>

namespace jvm {
namespace heap {

Slots::Slots(uint slotCount) : m_slots(slotCount) {}

void Slots::setInt(uint index, int32_t val) {
    m_slots[index].num = val;
}

int32_t Slots::getInt(uint index) const {
    return m_slots[index].num;
}

void Slots::setFloat(uint index, float val) {
    uint32_t bits = *reinterpret_cast<uint32_t*>(&val);
    m_slots[index].num = static_cast<int32_t>(bits);
}

float Slots::getFloat(uint index) const {
    uint32_t bits = static_cast<uint32_t>(m_slots[index].num);
    return *reinterpret_cast<const float*>(&bits);
}

void Slots::setLong(uint index, int64_t val) {
    m_slots[index].num = static_cast<int32_t>(val);
    m_slots[index + 1].num = static_cast<int32_t>(val >> 32);
}

int64_t Slots::getLong(uint index) const {
    uint32_t low = static_cast<uint32_t>(m_slots[index].num);
    uint32_t high = static_cast<uint32_t>(m_slots[index + 1].num);
    return (static_cast<int64_t>(high) << 32) | low;
}

void Slots::setDouble(uint index, double val) {
    uint64_t bits = *reinterpret_cast<uint64_t*>(&val);
    setLong(index, static_cast<int64_t>(bits));
}

double Slots::getDouble(uint index) const {
    uint64_t bits = static_cast<uint64_t>(getLong(index));
    return *reinterpret_cast<const double*>(&bits);
}

void Slots::setRef(uint index, Object* pRef) {
    m_slots[index].pRef = pRef;
}

Object* Slots::getRef(uint index) const {
    return m_slots[index].pRef;
}

} // namespace heap
} // namespace jvm